package com.wanmait.teatrain.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.wanmait.teatrain.entity.Admin;
import com.wanmait.teatrain.entity.Login;
import com.wanmait.teatrain.entity.Menu;
import com.wanmait.teatrain.mapper.AdminMapper;
import com.wanmait.teatrain.mapper.LoginMapper;
import com.wanmait.teatrain.mapper.MenuMapper;
import com.wanmait.teatrain.service.AdminService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wanmait.teatrain.service.LoginService;
import com.wanmait.teatrain.service.MenuService;
import com.wanmait.teatrain.utils.AjaxResult;
import com.wanmait.teatrain.utils.BusinessCode;
import com.wanmait.teatrain.utils.BusinessException;
import com.wanmait.teatrain.utils.JWTUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 管理员/用户表 服务实现类
 * </p>
 *
 * @author wanmait
 * @since 2025-10-22
 */
@Service
@Transactional
public class AdminServiceImpl extends ServiceImpl<AdminMapper, Admin> implements AdminService {
    @Resource
    private RedisTemplate<String,Object> redisTemplate;
    @Resource
    private AdminMapper adminMapper;
    //Token过期时间
    @Value("${token.expireMinutes}")
    private int expireMinutes;
    @Value("${token.secret}")
    private String secret;
    @Resource
    private LoginMapper loginMapper;
    @Resource
    private LoginService loginService;
    @Resource
    private MenuMapper menuMapper;
    @Resource
    private MenuService menuService;
    @Override
    public AjaxResult login(Admin admin, String code, String codeKey) {
        if(codeKey==null){
            throw new BusinessException(com.wanmait.teatrain.utils.BusinessCode.CAPTCHA_EXPIRED);
        }
        //从redis中找出正确的验证码
        String rightCode = (String) redisTemplate.opsForValue().get("code:"+codeKey);
        if(rightCode==null){
            throw new BusinessException(com.wanmait.teatrain.utils.BusinessCode.CAPTCHA_EXPIRED);
        }
        if(!rightCode.equalsIgnoreCase(code)){
            throw new BusinessException(com.wanmait.teatrain.utils.BusinessCode.CAPTCHA_INCORRECT);
        }
        if (StringUtils.isBlank(admin.getUsername()) || StringUtils.isBlank(admin.getPassword())){
            throw new BusinessException(com.wanmait.teatrain.utils.BusinessCode.USER_USERNAME_PASSWORD_REQUIRED);
        }
        //比对账号密码正确与否
        LambdaQueryWrapper<Admin> adminLambdaQueryWrapper = new LambdaQueryWrapper<>();
        adminLambdaQueryWrapper.eq(admin.getUsername()!=null,Admin::getUsername,admin.getUsername());
        adminLambdaQueryWrapper.eq(admin.getPassword()!=null,Admin::getPassword,admin.getPassword());
        //loginEmp为对应的账号用户
        Admin loginEmp = adminMapper.selectOne(adminLambdaQueryWrapper);
        if (loginEmp == null){
            throw new BusinessException(com.wanmait.teatrain.utils.BusinessCode.USER_LOGIN_CREDENTIALS_ERROR);
        }

        //更新登录信息
        //创建一个新的更新对象，传入ip和登陆时间
        Admin updateEmp = new Admin();
        updateEmp.setId(loginEmp.getId());
        updateEmp.setLoginIp(admin.getLoginIp());
        updateEmp.setLoginTime(admin.getLoginTime());
        HashMap<String,String> claims = new HashMap<>();
        claims.put("createTime","1111111");
        String token = JWTUtils.createToken(loginEmp.getId().toString(),expireMinutes,secret,claims);
        //存到redis
        redisTemplate.opsForValue().set("token:"+token,loginEmp,expireMinutes, TimeUnit.MINUTES);
        //防止前端控制台可以看见密码
        loginEmp.setPassword(null);
        //将最新的登录信息更新
        adminMapper.updateById(updateEmp);
        //存入redis
        redisTemplate.opsForValue().set("token:"+token,loginEmp,expireMinutes, TimeUnit.MINUTES);
        //加入登录日志
        Login log = new Login();
        log.setAdminId(loginEmp.getId()).setIp(admin.getLoginIp()).setCreateTime(admin.getLoginTime());
        loginService.save(log);
        //菜单树
        List<Menu> menuTree = menuService.listMenuTree();
        //查询有权限的菜单id集合
        List<Integer> allowedMenuIds = menuService.listAllowedMenuIds(loginEmp.getId());
        //用户所有的权限的字符串集合
        List<String> permsList = menuService.listPerms(loginEmp.getId());
        return AjaxResult.success()
                .put("token",token)
                .put("admin",loginEmp)
                .put("allowedMenuIds",allowedMenuIds)
                .put("menuTree",menuTree)
                .put("permsList",permsList);
    }
}
